# -*- coding: utf-8 -*-
"""
@Time : 2024/3/4 9:00 PM
@Author: imamhusan
@Des: 授权模块
"""
from fastapi import Request, HTTPException, status, Depends
from fastapi.security.oauth2 import OAuth2PasswordBearer
from config import settings
import time
import jwt


oauth2 = OAuth2PasswordBearer(tokenUrl='/api/v1/user/oauth2')


def create_token(data: dict):
    try:
        data = data.copy()
        data.update({'exp': int(time.time() + settings.JWT_EXPIRE_TIME)})
        jwt_token = jwt.encode(payload=data, key=settings.JWT_KEY, algorithm=settings.JWT_ALGORITHM)
        return jwt_token
    except Exception as e:
        return str(e)


async def verify_token(req: Request, token=Depends(oauth2)):
    try:
        payload = jwt.decode(jwt=token, key=settings.JWT_KEY, algorithms=[settings.JWT_ALGORITHM])
        if payload:
            user_id = payload.get('user_id', None)
            user_type = payload.get('user_type', None)
            session_id = payload.get('session_id', None)

            cached_session_id = await req.app.state.token_redis.get(name=user_id)

            if session_id != cached_session_id:
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail='账号已被其他设备登录！',
                    headers={"WWW-Authenticate": f"Bearer {token}"}
                )
            req.state.user_id = user_id
            req.state.user_type = user_type
        else:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail='未通过身份验证',
                headers={"WWW-Authenticate": f"Bearer {token}"}
            )

    except jwt.ExpiredSignatureError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail='已过期token',
            headers={"WWW-Authenticate": f"Bearer {token}"}
        )

    except jwt.InvalidTokenError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail='无效token',
            headers={"WWW-Authenticate": f"Bearer {token}"}
        )

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=str(e)
        )
